﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Kokomo.Mirror.CliMetadata
{
	class CliGenericType : CliImplementedType
	{
		private CliImplementedType _definition;
		private Type[] _genericArguments;

		internal CliGenericType(
			CliMemberBasicInfo basicInfo,
			CliImplementedType genericTypeDefinition,
			Type[] genericArguments
			)
			: base(basicInfo)
		{
			this._definition = genericTypeDefinition;
			this._genericArguments = genericArguments;
		}

		internal override Tables.TypeDefRow TypeDefRow
		{
			get { return this._definition.TypeDefRow; }
		}

		public override string AssemblyQualifiedName
		{
			get { return this.FullName + ", " + this.Assembly.FullName; }
		}

		public override Type BaseType
		{
			get { return this._definition.BaseType; }
		}

		public override string FullName
		{
			get
			{
				StringBuilder builder = new StringBuilder();
				builder.Append(this._definition.FullName);
				builder.Append("[[");
				builder.Append(this._genericArguments[0].AssemblyQualifiedName);
				for (int i = 1; i < this._genericArguments.Length; i++)
				{
					builder.Append("],[");
					builder.Append(this._genericArguments[i].AssemblyQualifiedName);
				}
				builder.Append("]]");
				return builder.ToString();
			}
		}

		public override Guid GUID
		{
			get { return this._definition.GUID; }
		}

		protected override System.Reflection.TypeAttributes GetAttributeFlagsImpl()
		{
			return this._definition.Attributes;
		}

		public override string Name
		{
			get { return this._definition.Name; }
		}

		public override string Namespace
		{
			get { return this._definition.Namespace; }
		}

		public override bool IsGenericType
		{
			get { return true; }
		}

		public override Type[] GetGenericArguments()
		{
			return this._genericArguments;
		}

		public override Type GetGenericTypeDefinition()
		{
			return this._definition;
		}

		public override Type Reflect()
		{
			Type definition = this._definition.Reflect();
			Type[] typeArgs = Array.ConvertAll(this.GetGenericArguments(), CliReflector.Reflect);
			return definition.MakeGenericType(typeArgs);
		}
	}
}
